package com.ruoyi.web.controller.app;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.password.PasswordUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.ruoyi.web.controller.tool.PriceRange;
import com.ruoyi.web.core.config.Configs;
import com.ruoyi.web.core.config.WebSocket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Api("App通用接口管理页面")
@RequestMapping("/app")
@RestController
public class AppInterfaceController extends BaseController {


    @Autowired
    private DdAddressService ddAddressService;

    @Autowired
    private IDdUserService ddUserService;

    @Autowired
    private IDdUserRiderService ddUserRiderService;

    @Autowired
    private IDdOrderService ddOrderService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IDdOrderInfoService orderInfoService;

    @Autowired
    private IDdOrderImgService orderImgService;

    @Autowired
    private WebSocket webSocket;

    // 地址——————————————————————————————————————————————————————————————————————
    @ApiOperation("查询地址集合")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "UID", defaultValue = "100", value = "用户ID"),
            @ApiImplicitParam(name = "sOrT", defaultValue = "0", value = "送货地址或者送达地址 0 送货 1送达")
    })
    @PostMapping("/selectByUID")
    public AjaxResult selectByUID(String UID, String sOrT) {
        return AjaxResult.success(ddAddressService.selectByUID(UID, sOrT));
    }

    @ApiOperation("新增常用地址")
    @PostMapping("/addAddress")
    public AjaxResult addAddress(DdAddress ddAddress) {
        return toAjax(ddAddressService.insertSelective(ddAddress));
    }

    @ApiOperation("删除常用地址")
    @ApiImplicitParam(name = "id", value = "地址ID")
    @PostMapping("/delAddress")
    public AjaxResult delAddress(int id) {
        return toAjax(ddAddressService.deleteByPrimaryKey(id));
    }

    @ApiOperation("修改常用地址")
    @ApiImplicitParam(name = "id", required = true, value = "用户ID")
    @PostMapping("/updateAddress")
    public AjaxResult updateAddress(DdAddress ddAddress) {
        return toAjax(ddAddressService.updateByPrimaryKeySelective(ddAddress));
    }


    // 地址——————————————————————————————————————————————————————————————————————


    // 订单——————————————————————————————————————————————————————————————————————
    @ApiOperation("订单列表")
    @PostMapping("/orderList")
    public AjaxResult orderList(DdOrder ddOrder) {
        List<DdOrder> ddOrders = ddOrderService.selectDdOrderList(ddOrder);
        return AjaxResult.success(ddOrders);
    }

    @ApiOperation("骑手待接单订单列表")
    @PostMapping("/unOrders")
    public AjaxResult unOrders(String status, String lat, String lng) {
        DdOrder ddOrder = new DdOrder();
        ddOrder.setStatus(status);
        List<DdOrder> ddOrders = ddOrderService.selectDdOrderList(ddOrder);
        List<DdOrder> orders = new ArrayList<>();
        for (DdOrder order : ddOrders){
            String distance = AddressUtils.getDistance(lat,lng,order.getBeginLat(),order.getBeginLng());
            if(Integer.parseInt(distance) <= Configs.RIDER_DISTANCE){
                orders.add(order);
            }
        }
        return AjaxResult.success(orders);
    }


//    @ApiImplicitParam(name = "status", value = "是否完成（0未完成 1完成 2待接单 3未支付 4取消订单）")
    @ApiImplicitParam(name = "params", value = "用户ID")
    @ApiOperation("下单")
    @PostMapping("/addOrder")
    public AjaxResult addOrder(DdOrder ddOrder, Map params) {
        StringBuffer str = new StringBuffer();
        StringBuffer str2 = new StringBuffer();
        Random random = new Random();
        for (int i=0; i < 3;i++){
            str.append(random.nextInt(10));
        }
        for (int i=0; i < 3;i++){
            str2.append(random.nextInt(10));
        }
        // 生成订单号
        ddOrder.setUuid(DateUtils.dateTimeNow()+str.toString()+ddOrder.getFromId()+ddOrder.getOrderType()+str2.toString());
        ddOrder.setCreateBy(ddOrder.getFromName());
        ddOrder.setCreateTime(DateUtils.getNowDate());
        int i = ddOrderService.insertDdOrder(ddOrder);
        if (i != 0) {
            // 订单信息加入 redis
//            redisTemplate.opsForList().leftPush("order", ddOrder);
        }
        return AjaxResult.success(ddOrderService.selectDdOrderById(ddOrder.getUuid()));
    }
    @ApiOperation("查询订单详情信息")
    @PostMapping("/orderInfo")
    public AjaxResult orderInfo(String uuid) {
        return AjaxResult.success(ddOrderService.selectDdOrderById(uuid));
    }

    @ApiOperation("删除订单")
    @PostMapping("/delOrder")
    public AjaxResult delOrder(DdOrder order) {
         order.setStatus("5");
        return toAjax(ddOrderService.updateDdOrder(order));
    }

    // 订单——————————————————————————————————————————————————————————————————————

    // 骑手——————————————————————————————————————————————————————————————————————
    @ApiOperation("骑手更新订单信息")
    @PostMapping("/orderUpdateRider")
    public AjaxResult orderUpdateRider(DdOrder order, String orderInfo){
        if(StringUtils.isNotNull(orderInfo)){
            DdOrderInfo info = JSONUtil.toBean(orderInfo, DdOrderInfo.class);
            ddOrderService.updateDdOrder(order);
            orderInfoService.insertDdOrderInfo(info);
            System.err.println(info.getStatus() == 0);
            if(info.getStatus() == 0){
                DdUserRider rider = new DdUserRider();
                rider.setUserId(order.getRiderId());
                rider.setOpen("0");
                ddUserRiderService.updateDdUserRider(rider);
            }else if(info.getStatus() == 3){
                DdUserRider rider = new DdUserRider();
                rider.setUserId(order.getFromId());
                rider.setOpen("1");
                ddUserRiderService.updateDdUserRider(rider);
            }

            return AjaxResult.success();
        }
        return error();
    }
    @ApiOperation("查询进行中订单详情")
    @PostMapping("/orderInfoList")
    public AjaxResult orderInfoList(DdOrderInfo info){
        if(StringUtils.isNotNull(info.getOid())){
            Map m = new HashMap();
            List<DdOrderInfo> infos = orderInfoService.selectDdOrderInfoList(info);
            m.put("infos", infos);
            if(infos.size() < 3 && infos.size() != 0){
                String address = (String) redisTemplate.opsForValue().get(infos.get(0).getOid());
                m.put("address",address);
            }
            DdOrderImg img = new DdOrderImg();
            img.setOid(info.getOid());
            m.put("imgs",orderImgService.selectDdOrderImgList(img));
            return AjaxResult.success(m);
        }
        return error();
    }

    @ApiOperation("更新骑手最新位置")
    @PostMapping("/updateNewAddress")
    public AjaxResult updateNewAddress(String uid, String lng, String lat) {
        Map m = new HashMap();
        m.put("lng", lng);
        m.put("lat", lat);
        try {

//            redisTemplate.opsForList().leftPush(uid,m);
            redisTemplate.opsForValue().set(uid, JSONUtil.toJsonPrettyStr(m));
//            redisTemplate.opsForValue().append(uid, JSONUtil.toJsonPrettyStr(m));
        } catch (RuntimeException e) {
            logger.error("更新骑手最新位置时发生错误:{}", e.getMessage());
            return error();
        }
        return success();
    }


    @ApiOperation("删除待接单骑手")
    @PostMapping("/delNewAddress")
    public AjaxResult delAddress(String uid) {
        try {
            redisTemplate.opsForSet().remove(uid);
        } catch (RuntimeException e) {
            logger.error("删除骑手位置时发生错误:{}", e.getMessage());
            logger.error("删除骑手位置时发生错误:{}", e.getMessage());
            return error();
        }
        return success();
    }

    @ApiOperation("请求骑手信息")
    @PostMapping("/riderInfo")
    public AjaxResult riderInfo(Long userId){
        if(StringUtils.isNotNull(userId)){
            return AjaxResult.success(ddUserRiderService.selectDdUserRiderById(userId));
        }
        return error();
    }

    @ApiOperation("开始接单")
    @PostMapping("/riderOpen")
    public AjaxResult riderOpen(Long userId){
        if(StringUtils.isNotNull(userId)){
            DdUserRider rider = new DdUserRider();
            rider.setUserId(userId);
            rider.setOpen("1");
            return toAjax(ddUserRiderService.updateDdUserRider(rider));
        }
        return error();
    }


    // 骑手——————————————————————————————————————————————————————————————————————
    @ApiOperation("上传图片")
    @PostMapping("/addImg")
    public AjaxResult addImg(DdOrderImg img){
        img.setUuid(UUID.randomUUID().toString());
        return toAjax(orderImgService.insertDdOrderImg(img));
    }



    @ApiOperation("验证码登录")
    @ApiImplicitParam(name = "isRider", value = "true or false", required = true, dataType = "Boolean")
    @PostMapping("/logUser")
//    @Log(title = "app登录")
    public AjaxResult logUser(Boolean isRider, String phone, String password) {
        if (StringUtils.isNull(phone) || StringUtils.isNull(password)) {
            return error("请填写正确的手机号和密码");
        }
        AjaxResult result;
        if (isRider) {
            result = ddUserRiderService.logUser(phone, password);
        } else {
            result = ddUserService.logUser(phone, password);
        }
        if (result.get("code").equals(0)) {
            Random ran = new Random();
            StringBuffer sms = new StringBuffer();
            for (int i = 0; i < 6; i++) {
                sms.append(ran.nextInt(10));
            }
            logger.info("验证码为：{}", sms);
            SMSUtils.sendSMS(phone, sms.toString());
            result.put("sms", sms.toString());
        }
        return result;
    }

    @ApiOperation("账号注册")
    @ApiImplicitParam(name = "isRider", value = "true or false", required = true, dataType = "Boolean")
    @PostMapping("/signUp")
    public AjaxResult signUp(Boolean isRider, String phonenumber, String password){
        // 注册
        if(isRider){
            DdUserRider ddUser = new DdUserRider();
            ddUser.setPhonenumber(phonenumber);
            ddUser.setLoginDate(DateUtils.getNowDate());
            ddUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
            ddUser.setSex("0");
            ddUser.setUserName(phonenumber);
            ddUser.setLoginName(phonenumber);
            ddUser.setCreateBy(phonenumber);
            ddUser.setCreateTime(DateUtils.getNowDate());
            ddUser.setSalt(PasswordUtils.randomSalt());
            ddUser.setPassword(PasswordUtils.encryptPassword(phonenumber,password,ddUser.getSalt()));
            int result = ddUserRiderService.insertDdUserRider(ddUser);
            if(result != 0){
                AjaxResult aj = new AjaxResult(AjaxResult.Type.SUCCESS,"注册成功");
                aj.put("sms",ddUser.getUserId()+"");
                return aj;
            }else {
                return error();
            }
        }else{
            DdUser ddUser = new DdUser();
            ddUser.setPhonenumber(phonenumber);
            ddUser.setLoginDate(DateUtils.getNowDate());
            ddUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
            ddUser.setSex("0");
            ddUser.setUserName(phonenumber);
            ddUser.setLoginName(phonenumber);
            ddUser.setCreateBy(phonenumber);
            ddUser.setCreateTime(DateUtils.getNowDate());
            ddUser.setSalt(PasswordUtils.randomSalt());
            ddUser.setPassword(PasswordUtils.encryptPassword(phonenumber,password,ddUser.getSalt()));
            int result = ddUserService.insertDdUser(ddUser);
            if(result != 0){
                AjaxResult aj = new AjaxResult(AjaxResult.Type.SUCCESS,"注册成功");
                aj.put("sms",ddUser.getUserId()+"");
                return aj;
            }else {
                return error();
            }
        }

    }

    @ApiOperation("登录")
    @ApiImplicitParam(name = "isRider", value = "true or false", required = true, dataType = "Boolean")
    @PostMapping("/signUser")
//    @Log(title = "app登录")
    public AjaxResult signUser(Boolean isRider, String phone, String password) {
        if (StringUtils.isNull(phone) || StringUtils.isNull(password)) {
            return error("请填写正确的手机号和密码");
        }
        AjaxResult result;
        if (isRider) {
            result = ddUserRiderService.logUser(phone, password);
        } else {
            result = ddUserService.logUser(phone, password);
        }
        return result;
    }

    @ApiOperation("发送短信")
    @PostMapping("/sendSMS")
    public AjaxResult sendSMS(String phone,String smsType){
        AjaxResult aj = new AjaxResult(AjaxResult.Type.SUCCESS,"操作成功");
        if(smsType.equals("0")){
            // 注册短信
            Random ran = new Random();
            StringBuffer sms = new StringBuffer();
            for (int i = 0; i < 6; i++) {
                sms.append(ran.nextInt(10));
            }
            logger.info("验证码为：{}", sms);
            SMSUtils.sendSMS(phone, sms.toString());
            aj.put("sms",sms);
            return aj;
        }
        return error();
    }



    @PostMapping("getPrice")
    @ApiOperation("计算价格")
    public AjaxResult getPrice(Double range) {
        AjaxResult aj = null;
        List<DdPrice> prices = new ArrayList<DdPrice>();

        int i = 0;
        while (i <= PriceRange.list.size()) {
            // 起步价
            if (i == 0) {
                if(range >= PriceRange.START_RANGE){
                    prices.add(new DdPrice(i,PriceRange.START_PRICE,PriceRange.START_RANGE));
                }else{
                    prices.add(new DdPrice(i,PriceRange.START_PRICE,range));
                }
                range = Arith.sub(range,PriceRange.START_RANGE);
            }else{
                //档位提价
                if(range >= 0){
                    DdPrice ddPrice = PriceRange.list.get(i-1);
                    if(range <= ddPrice.getRange()){
                        // 在提价范围区间
                        prices.add(new DdPrice(i,Arith.mul(range,ddPrice.getPrice()),range));
                    }else if (i == PriceRange.list.size()){
                        // 最后阶段
                        prices.add(new DdPrice(i,Arith.mul(range,ddPrice.getPrice()),range));
                    }else{
                        // 超出提价范围 进入下一档位
                        prices.add(new DdPrice(i,Arith.mul(ddPrice.getRange(),ddPrice.getPrice()),ddPrice.getRange()));
                    }
                    range = Arith.sub(range,ddPrice.getRange());
                }else{
                    prices.add(new DdPrice(i,0,0));
                }
            }
            i++;
        }
        double sum = 0.0;
        for (DdPrice price : prices){
            sum = Arith.add(sum,price.getPrice());
        }
        aj = new AjaxResult(AjaxResult.Type.SUCCESS,"操作成功",prices);
        aj.put("price",sum);

        return aj;
    }


}
